import gsap from "gsap/all";
import * as PIXI from "pixi.js";
import { DropElement } from "./dropBase";

// 红包元素
export class RedPackage extends DropElement {
  width = 60;

  height = 90;

  dropDuration =
    (this.gameConfig?.animations?.redPackageDuration || 2000) / 1000;

  url = this.gameConfig?.assets?.redPackageImg || DEFAULT_URL;

  initPositions = [
    [window.innerWidth * 0.25, 0],
    [window.innerWidth * 0.5, 0],
    [window.innerWidth * 0.75, 0],
  ];

  initAngles = [-15, 0, 15];

  //   点击红包
  onClick(e) {
    const { x, y } = e.data.global;

    // 在回调中拿到当前的最新总计分
    this.emit("redPackageClick", (score) => {
      // 移除红包动画
      this.createRedPackRemoveAnimation();

      // 圆圈动画
      this.createTouchCircleAnimation(x, y);

      // 分数动画
      this.createScoreAnimation(x, y, score);
    });
  }

  //  红包消失动画
  createRedPackRemoveAnimation() {
    const { redPackageEaseOut = 200 } = this.gameConfig?.animations || {};

    this.changeOpacity(this.element, redPackageEaseOut / 1000, 1, 0);

    setTimeout(() => {
      this.destroy(this.element);
    }, redPackageEaseOut + 100);
  }

  //   点击时的圆圈动画
  createTouchCircleAnimation(x, y) {
    const bigCircle = this.drawCircle(x, y, 25);
    const smallCircle = this.drawCircle(x, y, 15);

    this.app.stage.addChild(bigCircle);
    this.app.stage.addChild(smallCircle);

    // 第一阶段，小圈大圈同速率放大, 放大, 比例0 -> 1
    this.changeScale(bigCircle, 0.18, [0, 0], [1, 1]);
    this.changeScale(smallCircle, 0.18, [0, 0], [1, 1]);

    // 第二阶段，小圈固定，大圈接着放大，比例1 -> 1.6。同时大圈小圈开始渐隐。
    setTimeout(() => {
      this.changeScale(bigCircle, 0.25, [1, 1], [1.6, 1.6]);
      this.changeOpacity(smallCircle, 0.5, 1, 0);
      this.changeOpacity(bigCircle, 0.5, 1, 0);
    }, 180);

    // 销毁
    setTimeout(() => {
      this.destroy(bigCircle, smallCircle);
    }, 600);
  }

  //   分数动画
  createScoreAnimation(x, y, score) {
    const textX = this.drawScore("x", x + 50, y + 20, 20); // 乘号
    const textScore = this.drawScore(score, x + 65, y + 20, 40); // 分数

    const container = new PIXI.Container();
    container.x = x + 50;
    container.y = y + 20;
    container.pivot.x = x + 50;
    container.pivot.y = y + 20;
    container.addChild(textX, textScore);

    this.app.stage.addChild(container);

    // 第一阶段，分数渐显，并上升
    this.changeOpacity(container, 0.4, 0, 1);
    this.changeTranslate(container, 0.6, [0, -60]);

    // 第二阶段， 分数渐隐，并缩小
    setTimeout(() => {
      this.changeOpacity(container, 0.25, 1, 0);
      this.changeScale(container, 0.25, [1, 1], [0, 0]);
    }, 600);

    // 销毁
    setTimeout(() => {
      this.destroy(container);
    }, 1000);
  }

  //   放大动画
  changeScale(container, duration = 0.5, from = [0, 0], to = [1, 1]) {
    const [fromX, fromY] = from;
    const [toX, toY] = to;

    container.scale.x = fromX;
    container.scale.y = fromY;

    gsap.to(container.scale, { x: toX, y: toY, duration, ease: "none" });
  }

  //   渐隐动画
  changeOpacity(container, duration = 0.5, from = 0, to = 1) {
    container.alpha = from;
    gsap.to(container, { alpha: to, duration, ease: "none" });
  }

  //   位移动画
  changeTranslate(container, duration = 0.5, translate = [1, 1]) {
    const [translateX, translateY] = translate;

    gsap.to(container, { x: container.x + translateX, duration, ease: "none" });
    gsap.to(container, { y: container.y + translateY, duration, ease: "none" });
  }

  //   画圈
  drawCircle(x, y, radius) {
    const graphics = new PIXI.Graphics();

    graphics.x = x;
    graphics.y = y;
    graphics.pivot.x = x;
    graphics.pivot.y = y;

    graphics.beginFill(0xffd700, 0.3);
    graphics.drawCircle(x, y, radius);
    graphics.endFill();

    return graphics;
  }

  //   画分
  drawScore(text, x, y, size) {
    const style = new PIXI.TextStyle({
      fontSize: size,
      fontWeight: "bold",
      fill: "#FFDC1F",
    });

    const scoreText = new PIXI.Text(`${text}`, style);
    scoreText.x = x;
    scoreText.y = y;

    scoreText.anchor.set(0, 0.5);

    return scoreText;
  }

  //   销毁
  destroy(...args) {
    args.forEach((item) => {
      this.app.stage?.removeChild?.(item);
      item = null;
    });
  }
}
